package com.jichangxiu.dynamic.test.config;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.jichangxiu.dynamic.test.entity.Record;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 维护动态数据源
 *
 * @author Jcx
 * @date 2022/11/27 7:42
 */
@Slf4j
public class DynamicDataSourceService {

    private static final Map<Object, Object> dataSources = new HashMap<>();
    private static final ThreadLocal<String> dbKeys = ThreadLocal.withInitial(() -> null);

    /**
     * 构建DataSource
     *
     * @param url      数据库地址
     * @param username 用户名
     * @param password 用户密码
     * @return DataSource
     */
    public static DataSource buildDataSource(String url, String username, String password) throws Exception {
        return DruidDataSourceFactory.createDataSource(Record.getRecord("driverClassName", "com.mysql.cj.jdbc.Driver").set("username", username).set("password", password).set("url", url));
    }

    /**
     * 构建DataSource
     *
     * @param properties 配置文件
     * @return DataSource
     */
    public static DataSource buildDataSource(Properties properties) throws Exception {
        return DruidDataSourceFactory.createDataSource(properties);
    }

    /**
     * 动态添加一个数据源
     *
     * @param name       数据源的key
     * @param dataSource 数据源对象
     */
    public static void addDataSource(String name, DataSource dataSource) {
        DynamicDataSource dynamicDataSource = SpringUtil.getBean(DynamicDataSource.class);
        dataSources.put(name, dataSource);
        dynamicDataSource.setTargetDataSources(dataSources);
        dynamicDataSource.afterPropertiesSet();
        log.info("添加了数据源:{}", name);
    }

    /**
     * 动态添加一个数据源
     *
     * @param dbName   数据源的key
     * @param url      数据库地址
     * @param username 用户名
     * @param password 用户密码
     */
    public static void addDataSource(String dbName, String url, String username, String password) throws Exception {
        DataSource dataSource = buildDataSource(url, username, password);
        addDataSource(dbName, dataSource);
    }

    /**
     * 动态添加一个数据源
     *
     * @param dbName     数据源的key
     * @param properties 配置文件
     */
    public static void addDataSource(String dbName, Properties properties) throws Exception {
        DataSource dataSource = buildDataSource(properties);
        addDataSource(dbName, dataSource);
    }

    /**
     * 是否存在数据源
     */
    public static boolean exist(String dbKey) {
        return dataSources.get(dbKey) != null;
    }

    /**
     * 切换数据源
     */
    public static void switchDb(String dbKey) {
        dbKeys.set(dbKey);
    }

    /**
     * 重置数据源
     */
    public static void resetDb() {
        dbKeys.remove();
    }

    /**
     * 获取当前数据源
     */
    public static String currentDb() {
        return dbKeys.get();
    }
}

